package com.bluexmicro.ota2.ui.screen.dfu

import android.annotation.SuppressLint
import android.text.TextUtils
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material3.Button
import androidx.compose.material3.Card
import androidx.compose.material3.Divider
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavHostController
import com.bluexmicro.bluetooth.toUInt8
import com.bluexmicro.ota2.picker.device.LaunchDevicePicker
import com.bluexmicro.ota2.picker.file.LaunchFilePicker
import com.bluexmicro.ota2.ui.custom.DisplayItem
import com.bluexmicro.ota2.ui.custom.ErrorDialog
import com.bluexmicro.ota2.ui.custom.KeepScreenOnView
import com.bluexmicro.ota2.ui.custom.SubTopBar
import com.bluexmicro.ota2.ui.custom.TimeConsumingDialog
import com.bluexmicro.ota2.ui.custom.formatBytes
import com.bluexmicro.ota2.ui.custom.stepContent
import com.bluexmicro.ota2.ui.custom.stepTitle

@SuppressLint("MissingPermission")
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun DfuScreen(navHostController: NavHostController) {

    val viewModel: DfuViewModel = viewModel()
    val context = LocalContext.current

    val items = remember {
        viewModel.items
    }

    val target = remember {
        viewModel.target
    }

    val canUpdate = remember {
        viewModel.canUpdate
    }

    val progress = remember {
        derivedStateOf {
            (viewModel.progress.value * 100).toInt()
        }
    }

    val updating = remember {
        viewModel.updating
    }

    var error by remember {
        viewModel.error
    }

    var timeConsuming by remember {
        viewModel.timeConsuming
    }

    LaunchedEffect(viewModel.updating) {
        snapshotFlow {
            viewModel.updating
        }.collect {
        }
    }

    val filePicker = rememberLauncherForActivityResult(contract = LaunchFilePicker(), onResult = {
        if (it != null) {
            viewModel.onFileSelected(context, it)
        }
    })

    val devicePicker = rememberLauncherForActivityResult(
        contract = LaunchDevicePicker(),
        onResult = {
            if (it != null) {
                viewModel.onDeviceSelected(it)
            }
        }
    )

    Scaffold(
        topBar = {
            SubTopBar(title = "固件升级(DFU)") {
                navHostController.popBackStack()
            }
        }
    ) {
        LazyColumn(
            modifier = Modifier.padding(it),
            contentPadding = PaddingValues(16.dp),
        ) {

            stepTitle(1, "选择升级包（zip压缩包）", items.value.isNotEmpty())

            stepContent {
                Card {
                    for (entry in items.value.withIndex()) {
                        val title = entry.value.run {
                            "${idx.toUInt8()}: $fileName"
                        }
                        val desc = "Size: ${formatBytes(entry.value.rawData.size.toLong())}"
                        DisplayItem(title, desc)
                        if (entry.index < items.value.lastIndex) {
                            Divider(thickness = Dp.Hairline)
                        }
                    }
                }
                Spacer(modifier = Modifier.height(8.dp))
                Button(onClick = { filePicker.launch("zip") }, enabled = !updating.value) {
                    Text(text = "选择")
                }
            }

            stepTitle(2, "选择待升级设备", target.value != null)

            stepContent {

                target.value?.let {
                    Card {
                        val name = if (TextUtils.isEmpty(it.device.name)) {
                            it.scanRecord?.deviceName ?: "N/A"
                        } else {
                            it.device.name
                        }
                        DisplayItem(title = name, desc = target.value?.device?.address ?: "未选择")
                    }
                    Spacer(modifier = Modifier.height(8.dp))
                }

                Button(onClick = { devicePicker.launch(Unit) }, enabled = !updating.value) {
                    Text(text = "选择")
                }
            }

            val desc = if (updating.value) {
                if (progress.value == 0) {
                    ": 正在连接、初始化设备..."
                } else {
                    ": ${progress.value}%"
                }
            } else {
                ""
            }
            stepTitle(3, "升级$desc", canUpdate.value)

            stepContent {
                Button(onClick = { viewModel.startUpdate(context) }, enabled = canUpdate.value) {
                    Text(text = "开始升级")
                }
                KeepScreenOnView(keepOn = updating.value, modifier = Modifier.size(8.dp))
            }
        }
    }
    if (error != null) {
        ErrorDialog(error = error!!) {
            error = null
        }
    } else {
        if (timeConsuming != null) {
            TimeConsumingDialog(timeConsuming = timeConsuming!!) {
                timeConsuming = null
            }
        }
    }
}





